package com.jichangxiu.socket.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.jichangxiu.socket.entity.SocketResult;
import com.jichangxiu.socket.enums.SocketType;
import com.jichangxiu.socket.service.WebSocket;
import org.springframework.stereotype.Component;

import java.io.Serializable;

@Component
public class SocketUtils implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 同步 能够从当前线程中取出 HttpServletRequest 并从中取出用户 ID 赋值给 from
     */
    public static Sync sync = new Sync();

    /**
     * 异步 不能取出用户 ID 只能手动设置 from
     */
    public static Async async = new Async();

    /**
     * 只能在同步情况下使用，发送人和接收人都是自己，也就是自己给自己发消息
     * 能够从当前线程中取出 HttpServletRequest 并从中取出用户 ID 赋值给 from 和 to
     */
    public static Self self = new Self();

    public static final class Sync {

        public Msg msg = new Msg();

        public Alert alert = new Alert();

        public Notify notify = new Notify();

        public static final class Msg {

            public void sendMsg(String to, String page, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getMsgRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendMsg(String to, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendMsg(String content) {
                SocketUtils.send(SocketResult.syncSocketResult(SocketResult.getMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendErrorMsg(String to, String page, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getErrorMsgRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendErrorMsg(String to, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getErrorMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendErrorMsg(String content) {
                SocketUtils.send(SocketResult.syncSocketResult(SocketResult.getErrorMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendSuccessMsg(String to, String page, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getSuccessMsgRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendSuccessMsg(String to, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getSuccessMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendSuccessMsg(String content) {
                SocketUtils.send(SocketResult.syncSocketResult(SocketResult.getSuccessMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendWarningMsg(String to, String page, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getWarningMsgRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendWarningMsg(String to, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getWarningMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendWarningMsg(String content) {
                SocketUtils.send(SocketResult.syncSocketResult(SocketResult.getWarningMsgRecord(content), SocketType.MODAL.getType()));
            }

        }

        public static final class Alert {

            public void sendAlert(String to, String page, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getAlertRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendAlert(String to, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendAlert(String content) {
                SocketUtils.send(SocketResult.syncSocketResult(SocketResult.getAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendErrorAlert(String to, String page, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getErrorAlertRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendErrorAlert(String to, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getErrorAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendErrorAlert(String content) {
                SocketUtils.send(SocketResult.syncSocketResult(SocketResult.getErrorAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendSuccessAlert(String to, String page, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getSuccessAlertRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendSuccessAlert(String to, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getSuccessAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendSuccessAlert(String content) {
                SocketUtils.send(SocketResult.syncSocketResult(SocketResult.getSuccessAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendWarningAlert(String to, String page, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getWarningAlertRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendWarningAlert(String to, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getWarningAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendWarningAlert(String content) {
                SocketUtils.send(SocketResult.syncSocketResult(SocketResult.getWarningAlertRecord(content), SocketType.MODAL.getType()));
            }

        }

        public static final class Notify {

            public void sendNotify(String to, String page, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getNotifyRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendNotify(String to, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendNotify(String content) {
                SocketUtils.send(SocketResult.syncSocketResult(SocketResult.getNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendErrorNotify(String to, String page, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getErrorNotifyRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendErrorNotify(String to, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getErrorNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendErrorNotify(String content) {
                SocketUtils.send(SocketResult.syncSocketResult(SocketResult.getErrorNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendSuccessNotify(String to, String page, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getSuccessNotifyRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendSuccessNotify(String to, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getSuccessNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendSuccessNotify(String content) {
                SocketUtils.send(SocketResult.syncSocketResult(SocketResult.getSuccessNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendWarningNotify(String to, String page, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getWarningNotifyRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendWarningNotify(String to, String content) {
                SocketUtils.send(SocketResult.syncSocketResult(to, SocketResult.getWarningNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendWarningNotify(String content) {
                SocketUtils.send(SocketResult.syncSocketResult(SocketResult.getWarningNotifyRecord(content), SocketType.MODAL.getType()));
            }

        }

    }

    public static final class Async {

        public Msg msg = new Msg();

        public Alert alert = new Alert();

        public Notify notify = new Notify();

        public static final class Msg {

            public void sendMsg(String from, String to, String page, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getMsgRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendMsg(String from, String to, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendMsg(String from, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, SocketResult.getMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendErrorMsg(String from, String to, String page, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getErrorMsgRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendErrorMsg(String from, String to, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getErrorMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendErrorMsg(String from, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, SocketResult.getErrorMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendSuccessMsg(String from, String to, String page, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getSuccessMsgRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendSuccessMsg(String from, String to, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getSuccessMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendSuccessMsg(String from, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, SocketResult.getSuccessMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendWarningMsg(String from, String to, String page, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getWarningMsgRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendWarningMsg(String from, String to, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getWarningMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendWarningMsg(String from, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, SocketResult.getWarningMsgRecord(content), SocketType.MODAL.getType()));
            }

        }

        public static final class Alert {

            public void sendAlert(String from, String to, String page, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getAlertRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendAlert(String from, String to, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendAlert(String from, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, SocketResult.getAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendErrorAlert(String from, String to, String page, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getErrorAlertRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendErrorAlert(String from, String to, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getErrorAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendErrorAlert(String from, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, SocketResult.getErrorAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendSuccessAlert(String from, String to, String page, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getSuccessAlertRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendSuccessAlert(String from, String to, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getSuccessAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendSuccessAlert(String from, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, SocketResult.getSuccessAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendWarningAlert(String from, String to, String page, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getWarningAlertRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendWarningAlert(String from, String to, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getWarningAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendWarningAlert(String from, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, SocketResult.getWarningAlertRecord(content), SocketType.MODAL.getType()));
            }

        }

        public static final class Notify {

            public void sendNotify(String from, String to, String page, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getNotifyRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendNotify(String from, String to, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendNotify(String from, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, SocketResult.getNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendErrorNotify(String from, String to, String page, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getErrorNotifyRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendErrorNotify(String from, String to, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getErrorNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendErrorNotify(String from, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, SocketResult.getErrorNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendSuccessNotify(String from, String to, String page, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getSuccessNotifyRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendSuccessNotify(String from, String to, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getSuccessNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendSuccessNotify(String from, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, SocketResult.getSuccessNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendWarningNotify(String from, String to, String page, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getWarningNotifyRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendWarningNotify(String from, String to, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, to, SocketResult.getWarningNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendWarningNotify(String from, String content) {
                SocketUtils.send(SocketResult.asyncSocketResult(from, SocketResult.getWarningNotifyRecord(content), SocketType.MODAL.getType()));
            }

        }

    }

    public static final class Self {

        public Msg msg = new Msg();

        public Alert alert = new Alert();

        public Notify notify = new Notify();

        public static final class Msg {

            public void sendMsg(String page, String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getMsgRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendMsg(String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendErrorMsg(String page, String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getErrorMsgRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendErrorMsg(String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getErrorMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendSuccessMsg(String page, String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getSuccessMsgRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendSuccessMsg(String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getSuccessMsgRecord(content), SocketType.MODAL.getType()));
            }

            public void sendWarningMsg(String page, String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getWarningMsgRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendWarningMsg(String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getWarningMsgRecord(content), SocketType.MODAL.getType()));
            }

        }

        public static final class Alert {

            public void sendAlert(String page, String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getAlertRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendAlert(String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendErrorAlert(String page, String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getErrorAlertRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendErrorAlert(String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getErrorAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendSuccessAlert(String page, String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getSuccessAlertRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendSuccessAlert(String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getSuccessAlertRecord(content), SocketType.MODAL.getType()));
            }

            public void sendWarningAlert(String page, String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getWarningAlertRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendWarningAlert(String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getWarningAlertRecord(content), SocketType.MODAL.getType()));
            }

        }

        public static final class Notify {

            public void sendNotify(String page, String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getNotifyRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendNotify(String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendErrorNotify(String page, String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getErrorNotifyRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendErrorNotify(String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getErrorNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendSuccessNotify(String page, String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getSuccessNotifyRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendSuccessNotify(String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getSuccessNotifyRecord(content), SocketType.MODAL.getType()));
            }

            public void sendWarningNotify(String page, String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getWarningNotifyRecord(content), page, SocketType.MODAL.getType()));
            }

            public void sendWarningNotify(String content) {
                SocketUtils.send(SocketResult.selfSocketResult(SocketResult.getWarningNotifyRecord(content), SocketType.MODAL.getType()));
            }

        }

    }

    /**
     * 往客户端发送
     *
     * @param socketResult WebSocket 传输对象
     *                     如果没有 from 消息是不会被接收的
     *                     如果没有 to 则消息会发送给所有已登录用户
     *                     如果有 to 则消息会发送给制定的用户，其他登录用户无法收到消息
     *                     如果没有 page 消息是不会被接收的
     */
    public static void send(SocketResult socketResult) {
        broadcast(JSONUtil.toJsonStr(socketResult));
    }

    /**
     * 广播消息
     *
     * @param content 字符串内容
     */
    private static void broadcast(String content) {
        if (ObjectUtil.isNotEmpty(WebSocket.broadcaster)) {
            WebSocket.broadcaster.broadcast(content);
        }
    }

}
